/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui;

import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import org.apache.log4j.Logger;
import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.bushe.swing.event.annotation.EventSubscriber;

import who.tmap.bo.Annotations;
import who.tmap.bo.AttrDef;
import who.tmap.bo.BizObjects;
import who.tmap.bo.TextStyle;
import who.tmap.bo.ThematicMap;
import who.tmap.bo.cd.CDTypes;
import who.tmap.bo.impl.BizObjectFactory;
import who.tmap.common.TMapException;
import who.tmap.toolkit.MappingToolKit;
import who.tmap.toolkit.impl.AnnotationsHelper;
import who.tmap.toolkit.impl.CartographicDisplayHelper;
import who.tmap.toolkit.shape.MapShape;
import who.tmap.toolkit.shape.PolygonShape;
import who.tmap.ui.event.ColorPatternCDSelected;
import who.tmap.ui.event.ColorPatternNbRangesHasChanged;
import who.tmap.ui.event.DataStructureHasChanged;
import who.tmap.ui.event.OtherCDSelected;
import who.tmap.ui.event.PointCDSelected;
import who.tmap.ui.event.ProportionalSymbolsCDSelected;
import who.tmap.ui.util.JDialogFontChooser;
import who.tmap.ui.util.MiscUIHelper;
import who.tmap.util.MiscHelper;
import javax.swing.JComboBox;

/**
 * The Annotations frame
 * @author stl
 */
public class JFrameAnnotations extends JInternalFrame {//implements SimpleObserver {

    private static Logger logger = Logger.getLogger(JFrameAnnotations.class);  
	
    private AnnotationsHelper colorPatternHelper =new AnnotationsHelper();
    
    private static final String DEFAULT_FONT_NAME ="Serif";	
    private static final String NOT_APPLICABLE ="N.A.";
    private static final String LABEL_COLUMN_DEFAULT ="Use default";  
    
    private JFrameAnnotations thisFrame =this;
    
    private ThematicMap thematicMap;  
	
	private MappingToolKit mtk =null;
	private JPanel jContentPane = null;
	
	private JLabel jLabelTitle = null;
	private JCheckBox jCheckBoxTitleVisible = null;
	private JCheckBox jCheckBoxTitleTransparentBackground = null;
	private JCheckBox jCheckBoxLegendVisible = null;
	private JCheckBox jCheckBoxLegendTransparentBackground = null;	
	private JCheckBox jCheckBoxLabelsVisible = null;
	private JCheckBox jCheckBoxLabelsTransparentBackground = null;	

	private JTabbedPane jTabbedPaneAnnotations = null;

	private JPanel jPanelTitle = null;
	private JPanel jPanelLabels = null;
	private JPanel jPanelLegend = null;
	private JButton jButtonTitleStyle = null;
	private JPanel jPanelTitleButtons = null;
	private JPanel jPanelLegendButtons = null;
	private JPanel jPanelLabelsInfo = null;
	private JLabel jLabelLabelsVisibleCondition = null;
	private JTextField jTextFieldLabelsVisibleCondition = null;
	private JButton jButtonLabelsStyle = null;
	private JButton jButtonHideLabelsForSelectedPolygons = null;
	private JButton jButtonShowLabelsForSelectedPolygons = null;	
	private JButton jButtonLegendStyle = null;
	private JCheckBox jCheckBoxLabelsVisibleIfDataExists = null;
	private JPanel jPanelButtons = null;
	private JButton jButtonApply = null;

	private JLabel jLabelLegendText = null;
	private JTextField jTextFieldLegendText = null;

	private boolean dirty =false;

	private JButton jButtonEditLegend = null;
	private JButton jButtonTitleEdit = null;
	private JButton jButtonLegendTitleEdit = null;
	
	private int selectedCD =CDTypes.DEFAULT_CD;

	private JLabel jLabelLabelColumn = null;
	private JComboBox jComboBoxLabelColumn = null;
	private boolean enableComboBoxLabelColumnEvent =false;
	

	public JFrameAnnotations() {
		super( "Annotations", 
			  true, //resizable
			  true, //closable
			  true, //maximizable
			  true);//iconifiable
		initialize();
	}
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		setSize(362, 318);
		this.setContentPane(getJContentPane());
		this.setContentPane(getJContentPane());
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setClosable( false );

		setFocusable( true );
		
		setFrameIcon( new MiscHelper().getImageIcon("ic_legende2.gif") );
		
		pack();
		
		AnnotationProcessor.process(this);
	}
	
	public boolean isDirty() {
		return dirty;
	}
	
	public void setDirty(boolean dirty) {
		this.dirty = dirty;
	}
	
	private void setDirty() {
		dirty =true;
	}
	
	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();

			jContentPane.setLayout(new BorderLayout());
  			jContentPane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
  			jContentPane.add(getJPanelButtons(), java.awt.BorderLayout.NORTH);  			
  			jContentPane.add(getJTabbedPaneAnnotations(), java.awt.BorderLayout.CENTER);

		}
		return jContentPane;
	}	
	
	/**
	 * This method initializes jLabelTitle
	 * 
	 * @return javax.swing.JLabel
	 */
	private JLabel getJLabelTitle() {
		if(jLabelTitle == null) {
			jLabelTitle = new JLabel();
			jLabelTitle.setText("");
		
		}
		return jLabelTitle;
	}
	
	/**
	 * This method initializes jCheckBoxTitle
	 * 
	 * @return JCheckBox
	 */
	private JCheckBox getJCheckBoxTitleVisible() {
		if(jCheckBoxTitleVisible == null) {
			jCheckBoxTitleVisible = new JCheckBox();
			jCheckBoxTitleVisible.setText("Show title");
			jCheckBoxTitleVisible.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setDirty();
					repaintThematicMap();
				}
			});
		}
		return jCheckBoxTitleVisible;
	}
	
	private JCheckBox getJCheckBoxTitleTransparentBackground() {
		if(jCheckBoxTitleTransparentBackground == null) {
			jCheckBoxTitleTransparentBackground = new JCheckBox();
			jCheckBoxTitleTransparentBackground.setText("Transparent");
			jCheckBoxTitleTransparentBackground.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setDirty();
					repaintThematicMap();
				}
			});
		}
		return jCheckBoxTitleTransparentBackground;
	}	
	
	/**
	 * This method initializes jCheckBoxLegend
	 * 
	 * @return JCheckBox
	 */
	private JCheckBox getJCheckBoxLegendVisible() {
		if(jCheckBoxLegendVisible == null) {
			jCheckBoxLegendVisible = new JCheckBox();
			jCheckBoxLegendVisible.setText("Show legend");
			jCheckBoxLegendVisible.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setDirty();
					repaintThematicMap();
				}
			});
		}
		return jCheckBoxLegendVisible;
	}
	
	private JCheckBox getJCheckBoxLegendTransparentBackground() {
		if(jCheckBoxLegendTransparentBackground == null) {
			jCheckBoxLegendTransparentBackground = new JCheckBox();
			jCheckBoxLegendTransparentBackground.setText("Transparent");
			jCheckBoxLegendTransparentBackground.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setDirty();
					repaintThematicMap();
				}
			});
		}
		return jCheckBoxLegendTransparentBackground;
	}	
	
	/**
	 * This method initializes jCheckBoxLabels
	 * 
	 * @return JCheckBox
	 */
	private JCheckBox getJCheckBoxLabelsVisible() {
		if(jCheckBoxLabelsVisible == null) {
			jCheckBoxLabelsVisible = new JCheckBox();
			jCheckBoxLabelsVisible.setText("Show labels");
			jCheckBoxLabelsVisible.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setDirty();
					repaintThematicMap();
				}
			});
		}
		return jCheckBoxLabelsVisible;
	}
	
	private JCheckBox getJCheckBoxLabelsTransparentBackground() {
		if(jCheckBoxLabelsTransparentBackground == null) {
			jCheckBoxLabelsTransparentBackground = new JCheckBox();
			jCheckBoxLabelsTransparentBackground.setText("Transparent");
			jCheckBoxLabelsTransparentBackground.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setDirty();
					repaintThematicMap();
				}
			});
		}
		return jCheckBoxLabelsTransparentBackground;
	}	
	
	/**
	 * This method initializes jTabbedPaneAnnotations	
	 * 	
	 * @return JTabbedPane	
	 */
	private JTabbedPane getJTabbedPaneAnnotations() {
		if (jTabbedPaneAnnotations == null) {
			jTabbedPaneAnnotations = new JTabbedPane();
			jTabbedPaneAnnotations.addTab("Title", null, getJPanelTitle(), null);
			jTabbedPaneAnnotations.addTab("Legend", null, getJPanelLegend(), null);
			jTabbedPaneAnnotations.addTab("Labels", null, getJPanelLabels(), null);
		}
		return jTabbedPaneAnnotations;
	}
	
	/**
	 * This method initializes jPanelTitle	
	 * 	
	 * @return JPanel	
	 */
	private JPanel getJPanelTitle() {
		if (jPanelTitle == null) {
			jPanelTitle =new JPanel();
			
			jPanelTitle.add(getJPanelTitleButtons());
		}
		return jPanelTitle;
	}
	
	/**
	 * This method initializes jPanelLegend	
	 * 	
	 * @return JPanel	
	 */
	private JPanel getJPanelLabels() {
		if (jPanelLabels == null) {
			jPanelLabels = new JPanel();
			
			jPanelLabels.add(getJPanelLabelsInfo());
		}
		return jPanelLabels;
	}
	
	/**
	 * This method initializes jPanelLabels	
	 * 	
	 * @return JPanel	
	 */
	private JPanel getJPanelLegend() {
		if (jPanelLegend == null) {
			jPanelLegend = new JPanel();
			
			jPanelLegend.add(getJPanelLegendButtons());
			getJButtonEditLegend().setVisible( false );
		}
		return jPanelLegend;
	}
		
	/**
	 * This method initializes jButtonTitleStyle	
	 * 	
	 * @return JButton	
	 */
	private JButton getJButtonTitleStyle() {
		if (jButtonTitleStyle == null) {
			jButtonTitleStyle = new JButton();
			jButtonTitleStyle.setText("Style...");
			jButtonTitleStyle.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
		        	TextStyle style =thematicMap.getAnnotations().getTitleStyle();
		        	
		        	thematicMap.getAnnotations().setTitleStyle( selectFont( style ) );
		        	
		        	repaintThematicMap();
				}
			});
		}
		return jButtonTitleStyle;
	}
	
	/**
	 * This method initializes jPanelTitleInfo	
	 * 	
	 * @return JPanel	
	 */
	private JPanel getJPanelTitleButtons() {
		if (jPanelTitleButtons == null) {
			
			jPanelTitleButtons = new JPanel();
			jPanelTitleButtons.setLayout( new GridLayout( 4, 1, 5, 5 ) );
			
			jPanelTitleButtons.add(getJCheckBoxTitleVisible());
			jPanelTitleButtons.add(getJButtonTitleStyle());
			jPanelTitleButtons.add( getJCheckBoxTitleTransparentBackground() );
			jPanelTitleButtons.add(getJButtonTitleEdit());
		
		}
		return jPanelTitleButtons;
	}
	
	/**
	 * This method initializes jPanelLegendInfo	
	 * 	
	 * @return JPanel	
	 */
	private JPanel getJPanelLegendButtons() {
		if (jPanelLegendButtons == null) {
			jPanelLegendButtons = new JPanel();
			jPanelLegendButtons.setLayout( new GridLayout( 6, 1, 5, 5  ) );
			
			jPanelLegendButtons.add(getJCheckBoxLegendVisible());
			jPanelLegendButtons.add(getJButtonLegendStyle());
			jPanelLegendButtons.add(getJCheckBoxLegendTransparentBackground());
			jPanelLegendButtons.add(getJButtonLegendTextEdit());
			jPanelLegendButtons.add(getJButtonEditLegend());
		}
		return jPanelLegendButtons;
	}
	
	/**
	 * This method initializes jPanelLabelsInfo	
	 * 	
	 * @return JPanel	
	 */
	private JPanel getJPanelLabelsInfo() {
		if (jPanelLabelsInfo == null) {
			jLabelLabelColumn = new JLabel();
			jLabelLabelColumn.setText("Label Column");
			GridLayout gridLayout1 = new GridLayout(9,1,5,5);
			
			jLabelLabelsVisibleCondition = new JLabel();
			jLabelLabelsVisibleCondition.setText("Show if data >");
			
			jPanelLabelsInfo = new JPanel();
			jPanelLabelsInfo.setLayout(gridLayout1);
			jPanelLabelsInfo.add(getJCheckBoxLabelsVisible());

			jPanelLabelsInfo.add(getJButtonLabelsStyle());
			jPanelLabelsInfo.add(jLabelLabelsVisibleCondition);
			jPanelLabelsInfo.add(getJTextFieldLabelsVisibleCondition());

			jPanelLabelsInfo.add(getJCheckBoxLabelsVisibleIfDataExists());
			
			jPanelLabelsInfo.add(jLabelLabelColumn);
			jPanelLabelsInfo.add(getJComboBoxLabelColumn(), null);
			
			jPanelLabelsInfo.add(getJButtonShowLabelsForSelectedPolygons());				
			jPanelLabelsInfo.add(getJButtonHideLabelsForSelectedPolygons());			
		}
		return jPanelLabelsInfo;
	}
	
	/**
	 * This method initializes jTextFieldLabelsDisplayOnlyIf	
	 * 	
	 * @return JTextField	
	 */
	private JTextField getJTextFieldLabelsVisibleCondition() {
		if (jTextFieldLabelsVisibleCondition == null) {
			jTextFieldLabelsVisibleCondition = new JTextField();
			jTextFieldLabelsVisibleCondition.setText( NOT_APPLICABLE );
			jTextFieldLabelsVisibleCondition
					.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							double val =0;
							try {
								val =Double.parseDouble( jTextFieldLabelsVisibleCondition.getText() );
								jTextFieldLabelsVisibleCondition.setText( Double.toString( val ) );
							} catch( Exception e2 ) {
								jTextFieldLabelsVisibleCondition.setText( NOT_APPLICABLE );
							}
							
							setDirty();
							
							repaintThematicMap();
						}
					});
		}
		return jTextFieldLabelsVisibleCondition;
	}
	
	/**
	 * This method initializes jButtonLabelsStyle	
	 * 	
	 * @return JButton	
	 */
	private JButton getJButtonLabelsStyle() {
		if (jButtonLabelsStyle == null) {
			jButtonLabelsStyle = new JButton();
			jButtonLabelsStyle.setText("Style...");
			jButtonLabelsStyle.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
		        	TextStyle style =thematicMap.getAnnotations().getLabelsStyle();
		        	
		        	thematicMap.getAnnotations().setLabelsStyle( selectFont( style ) );		
		        	
		        	repaintThematicMap();
		        }
			});
		}
		return jButtonLabelsStyle;
	}
	
	/**
	 * This method initializes jButtonHideLabelsForSelectedPolygons	
	 * 	
	 * @return JButton	
	 */
	private JButton getJButtonHideLabelsForSelectedPolygons() {
		if (jButtonHideLabelsForSelectedPolygons == null) {
			jButtonHideLabelsForSelectedPolygons = new JButton();
			jButtonHideLabelsForSelectedPolygons.setText("Hide for selected polygons");
			jButtonHideLabelsForSelectedPolygons.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setLabelsVisible( false );
		        }
			});
		}
		return jButtonHideLabelsForSelectedPolygons;
	}
	
	/**
	 * This method initializes jButtonShowLabelsForSelectedPolygons	
	 * 	
	 * @return JButton	
	 */	
	private JButton getJButtonShowLabelsForSelectedPolygons() {
		if (jButtonShowLabelsForSelectedPolygons == null) {
			jButtonShowLabelsForSelectedPolygons = new JButton();
			jButtonShowLabelsForSelectedPolygons.setText("Show for selected polygons");
			jButtonShowLabelsForSelectedPolygons.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
		        	setLabelsVisible( true );
		        }
			});
		}
		return jButtonShowLabelsForSelectedPolygons;
	}
	
	private void setLabelsVisible( boolean visible ) {
	    // Build a sorted collection of polygons
	    List<MapShape> polygons =mtk.getSelectedShapes();
	    
	    for( MapShape mapShape : polygons ) {
	    	PolygonShape polygonShape =(PolygonShape)mapShape;
	    	
	    	polygonShape.getLabelShape().setVisible( visible );
	    }
		
		repaintThematicMap();
	}
	
	public void setThematicMap( ThematicMap thematicMap ) {
		this.thematicMap =thematicMap;
	}
	
	public ThematicMap getThematicMap() {
		return thematicMap;
	}	
	
	public MappingToolKit getMtk() {
		return mtk;
	}
	
	public void setMtk(MappingToolKit mtk) {
		this.mtk = mtk;
	}
	/**
	 * This method initializes jButtonLegendStyle	
	 * 	
	 * @return JButton	
	 */
	private JButton getJButtonLegendStyle() {
		if (jButtonLegendStyle == null) {
			jButtonLegendStyle = new JButton();
			jButtonLegendStyle.setText("Style...");
			jButtonLegendStyle.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
		        	TextStyle style =thematicMap.getAnnotations().getLegendStyle();
		        	
		        	thematicMap.getAnnotations().setLegendStyle( selectFont( style ) );	
		        	
		        	repaintThematicMap();
		        }
			});
		}
		return jButtonLegendStyle;
	}
	
	/**
	 * This method initializes jCheckBoxLabelsDisplayIfDataExists	
	 * 	
	 * @return JCheckBox	
	 */
	private JCheckBox getJCheckBoxLabelsVisibleIfDataExists() {
		if (jCheckBoxLabelsVisibleIfDataExists == null) {
			jCheckBoxLabelsVisibleIfDataExists = new JCheckBox();
			jCheckBoxLabelsVisibleIfDataExists.setText("Show if data exists");
			jCheckBoxLabelsVisibleIfDataExists
					.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							setDirty();
							repaintThematicMap();
						}
					});
		}
		return jCheckBoxLabelsVisibleIfDataExists;
	}
	
	/**
	 * This method initializes jPanelButtons	
	 * 	
	 * @return JPanel	
	 */
	private JPanel getJPanelButtons() {
		if (jPanelButtons == null) {
			FlowLayout flowLayout = new FlowLayout();
			flowLayout.setAlignment(java.awt.FlowLayout.RIGHT);
			flowLayout.setVgap(5);
			flowLayout.setHgap(0);
			jPanelButtons = new JPanel();
			jPanelButtons.setLayout(flowLayout);
			jPanelButtons.add(getJButtonApply(), null);
		}
		return jPanelButtons;
	}
	/**
	 * This method initializes jButtonApply	
	 * 	
	 * @return JButton	
	 */
	private JButton getJButtonApply() {
		if (jButtonApply == null) {
			jButtonApply = new JButton();
			jButtonApply.setVisible( false );
			jButtonApply.setText("Apply");
			jButtonApply.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					repaintThematicMap();
				}
			});
		}
		return jButtonApply;
	}
	
	private void repaintThematicMap() {
		retrieveAnnotations();
		
		mtk.setAnnotationsVisible( true );
		mtk.repaint();		
	}
	
	public Annotations retrieveAnnotations() {
		Annotations annotations =thematicMap.getAnnotations();
		
		if ( annotations == null ) {
			try {
				annotations =(Annotations)BizObjectFactory.getInstance().get( BizObjects.ANNOTATIONS );
				thematicMap.setAnnotations( annotations );
				
			} catch (TMapException e) {
				new MiscUIHelper().displayErrorMessage( this, e );
			}
		}
		
		annotations.setTitleVisible( getJCheckBoxTitleVisible().isSelected() );
		annotations.setTitleBackgroundTransparent( getJCheckBoxTitleTransparentBackground().isSelected() );
		annotations.setLegendVisible( getJCheckBoxLegendVisible().isSelected() );
		annotations.setLegendBackgroundTransparent( getJCheckBoxLegendTransparentBackground().isSelected() );
		
		annotations.setLabelsVisible( getJCheckBoxLabelsVisible().isSelected() );
		double val =0;
		try {
			val =Double.parseDouble( getJTextFieldLabelsVisibleCondition().getText() );
			//annotations.setLabelsVisibleCondition( val );						
		} catch( Exception e2 ) {
			//annotations.setLabelsVisibleCondition( Double.MAX_VALUE );
		}
		annotations.setLabelsVisibleCondition( val );
		annotations.setLabelsVisibleIfDataExists( getJCheckBoxLabelsVisibleIfDataExists().isSelected() );
		annotations.setLabelColumnName( (String)getJComboBoxLabelColumn().getSelectedItem() );
		
		annotations.setGraphics( mtk.getShapes() );
		annotations.setDirty( isDirty() );
		
		return annotations;
	}
	
	public void refreshData() {
		Annotations annotations =thematicMap != null ? thematicMap.getAnnotations()
													 : null;
		
		if ( annotations != null ) {
			getJCheckBoxTitleVisible().setSelected( annotations.isTitleVisible() );			
			getJCheckBoxTitleTransparentBackground().setSelected( annotations.isTitleBackgroundTransparent() );
			getJCheckBoxLegendVisible().setSelected( annotations.isLegendVisible() );
			getJCheckBoxLegendTransparentBackground().setSelected( annotations.isLegendBackgroundTransparent() );
			
			getJCheckBoxLabelsVisible().setSelected( annotations.isLabelsVisible() );
			getJTextFieldLabelsVisibleCondition().setText( Double.toString( annotations.getLabelsVisibleCondition() ) );
			getJCheckBoxLabelsVisibleIfDataExists().setSelected( annotations.isLabelsVisibleIfDataExists() );
			
			enableComboBoxLabelColumnEvent =false;			
			if ( thematicMap != null && thematicMap.getData() != null ) {
				refreshColumnNames( thematicMap.getData().getHeader() );
			}

			if ( annotations.getLabelColumnName() != null ) {
				getJComboBoxLabelColumn().setSelectedItem( annotations.getLabelColumnName() );
			}
			enableComboBoxLabelColumnEvent =true;
		}
		
		setDirty( false );
	}
	
	private TextStyle selectFont( TextStyle style ) {
		JDialogFontChooser jFontChooser =new JDialogFontChooser( JOptionPane.getFrameForComponent(thisFrame), 
													 true, JDialogFontChooser.Role.FONT_STYLE_ONLY );
	    try {
         	if ( style != null ) {
	        	jFontChooser.applyStyle( style );
	        	
		        jFontChooser.applyValuesToUI();
		        jFontChooser.displayText();				        	
        	}
	    	        
	        jFontChooser.setVisible( true );
	        
	        if ( jFontChooser.isOkPressed() ) {	
	        	style =jFontChooser.getStyle();	        	
	        }
            
        } catch (Exception e1) {
            logger.error( e1 );
        } finally {
            jFontChooser.dispose();
        }					
        
        return style;
	}

	/*@SuppressWarnings("unchecked")
	public void sendNotify(Object msg) {
		if ( msg instanceof String ) {
			String str =(String)msg;
			logger.debug( "Received notification " + str );
			
			if ( str.startsWith( JFrameCartographicDisplay.COLORPATTERN_CD_SELECTED_MSG ) ) { 
				 //|| ( str.startsWith( JFrameCartographicDisplay.NB_RANGES_UPDATED_MSG ) ) ) ) { 
				selectedCD =CDTypes.COLOR_PATTERN;
				getJButtonEditLegend().setVisible( true );
				
				jLabelLabelColumn.setVisible( true );
				getJComboBoxLabelColumn().setVisible( true );
				
				int nbRanges =0;
				int classification =-1;
				if ( str.startsWith( JFrameCartographicDisplay.NB_RANGES_UPDATED_MSG ) ) {
					int idx =str.lastIndexOf( "_" );
					//nbRanges =Integer.parseInt( str.substring( JFrameCartographicDisplay.NB_RANGES_UPDATED_MSG.length() ) );
					nbRanges =Integer.parseInt( str.substring( JFrameCartographicDisplay.NB_RANGES_UPDATED_MSG.length(), idx ) );
					classification =Integer.parseInt( str.substring( idx + 1 ) );

				} else if ( str.startsWith( JFrameCartographicDisplay.COLORPATTERN_CD_SELECTED_MSG ) ) {
					//nbRanges =Integer.parseInt( str.substring( JFrameCartographicDisplay.COLORPATTERN_CD_SELECTED_MSG.length() ) );
					int idx =str.lastIndexOf( "_" );
					nbRanges =Integer.parseInt( str.substring( JFrameCartographicDisplay.COLORPATTERN_CD_SELECTED_MSG.length(), idx ) );
					classification =Integer.parseInt( str.substring( idx + 1 ) );
				//}
				
				logger.debug( "nbRanges=[" + nbRanges + "], classification=[" + classification + "]" );
				//CDColorPattern cdcp =(CDColorPattern)thematicMap.getCartographicDisplay();
				colorPatternHelper.applyRanges( nbRanges, thematicMap.getAnnotations(), classification );	
				
			} else if ( JFrameCartographicDisplay.PROPORTIONAL_SYMBOLS_CD_SELECTED_MSG.equals( str ) ) {
				selectedCD =CDTypes.PROPORTIONAL_SYMBOLS;
				getJButtonEditLegend().setVisible( true );
				
				jLabelLabelColumn.setVisible( true );
				getJComboBoxLabelColumn().setVisible( true );
				
			} else {
				
				selectedCD =-1;
				getJButtonEditLegend().setVisible( false );
				
				if ( JFrameCartographicDisplay.POINT_CD_SELECTED_MSG.equals( str ) ) {
					jLabelLabelColumn.setVisible( false );
					getJComboBoxLabelColumn().setVisible( false );
				} else {
					jLabelLabelColumn.setVisible( true );
					getJComboBoxLabelColumn().setVisible( true );
				}

			}
			
		} else {
			
			List<AttrDef> attrDefs = (List<AttrDef>)msg;
			enableComboBoxLabelColumnEvent =false;
			refreshColumnNames( attrDefs );
			enableComboBoxLabelColumnEvent =true;
			
		}
		
	}*/
	
	@EventSubscriber(eventClass=DataStructureHasChanged.class)
    public void onEvent(DataStructureHasChanged event) {
		logger.debug( "Notification received: " + event.getClass().getName() );
		
		List<AttrDef> attrDefs = event.getHeader();
		enableComboBoxLabelColumnEvent =false;
		refreshColumnNames( attrDefs );
		enableComboBoxLabelColumnEvent =true;
    }
	
	@EventSubscriber(eventClass=ColorPatternNbRangesHasChanged.class)
    public void onEvent(ColorPatternNbRangesHasChanged event) {
		logger.debug( "Notification received: " + event.getClass().getName() );	
		
		selectedCD =CDTypes.COLOR_PATTERN;
		getJButtonEditLegend().setVisible( true );
		
		jLabelLabelColumn.setVisible( true );
		getJComboBoxLabelColumn().setVisible( true );
				
		colorPatternHelper.applyRanges( event.getNbRanges(), thematicMap.getAnnotations(), 
										event.getAttrClassificationIdx() + 1 );
		
	}
	
	@EventSubscriber(eventClass=ColorPatternCDSelected.class)
    public void onEvent(ColorPatternCDSelected event) {
		logger.debug( "Notification received: " + event.getClass().getName() );	
		
		selectedCD =CDTypes.COLOR_PATTERN;
		getJButtonEditLegend().setVisible( true );
		
		jLabelLabelColumn.setVisible( true );
		getJComboBoxLabelColumn().setVisible( true );

		colorPatternHelper.applyRanges( event.getNbRanges(), thematicMap.getAnnotations(), 
										event.getAttrClassificationIdx() + 1 );		
	}	
	
	@EventSubscriber(eventClass=ProportionalSymbolsCDSelected.class)
    public void onEvent(ProportionalSymbolsCDSelected event) {
		logger.debug( "Notification received: " + event.getClass().getName() );	
		
		selectedCD =CDTypes.PROPORTIONAL_SYMBOLS;
		getJButtonEditLegend().setVisible( true );
		
		jLabelLabelColumn.setVisible( true );
		getJComboBoxLabelColumn().setVisible( true );
	}
	
	@EventSubscriber(eventClass=PointCDSelected.class)
    public void onEvent(PointCDSelected event) {
		logger.debug( "Notification received: " + event.getClass().getName() );	
		
		selectedCD =-1;
		getJButtonEditLegend().setVisible( false );
		
		jLabelLabelColumn.setVisible( false );
		getJComboBoxLabelColumn().setVisible( false );
	}	
	
	@EventSubscriber(eventClass=OtherCDSelected.class)
    public void onEvent(OtherCDSelected event) {
		logger.debug( "Notification received: " + event.getClass().getName() );	
		
		selectedCD =-1;
		getJButtonEditLegend().setVisible( false );
		
		jLabelLabelColumn.setVisible( true );
		getJComboBoxLabelColumn().setVisible( true );
	}
	
	private void refreshColumnNames( List<AttrDef> attrDefs  ) {
		String selection =(String)getJComboBoxLabelColumn().getSelectedItem();
		getJComboBoxLabelColumn().removeAllItems();
		
		getJComboBoxLabelColumn().addItem( LABEL_COLUMN_DEFAULT );

		if ( attrDefs != null ) {
			for( int ct =0; ct < attrDefs.size(); ct++ ) {
				AttrDef attrDef =(AttrDef)attrDefs.get( ct );
				
				getJComboBoxLabelColumn().addItem( attrDef.getName() );
				if ( attrDef.getName().equalsIgnoreCase( selection ) ) {
					getJComboBoxLabelColumn().setSelectedIndex( ct );
				}
			}
		}
		
		if ( selection == null ) {
			getJComboBoxLabelColumn().setSelectedIndex( 0 );
		}
		
	}
	
	/**
	 * This method initializes jButtonResetColorPatternDefault	
	 * 	
	 * @return JButton	
	 */
		private JButton getJButtonEditLegend() {
		if (jButtonEditLegend == null) {
			jButtonEditLegend = new JButton();
			jButtonEditLegend.setText( "Edit Legend..." );
			jButtonEditLegend.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
			jButtonEditLegend
					.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							if ( selectedCD == CDTypes.COLOR_PATTERN ) {
								if ( thematicMap.getAnnotations() != null && thematicMap.getAnnotations().getColorPatternLegend() != null ) {
									JDialogEditColorPatternLegend dlg =new JDialogEditColorPatternLegend( JOptionPane.getFrameForComponent( thisFrame ), 
																										  true, thisFrame.thematicMap.getAnnotations(), thematicMap.getCartographicDisplay() );
									dlg.setVisible( true );
									
									dlg.dispose();
									
									repaintThematicMap();
								} else {
									JOptionPane.showMessageDialog( JOptionPane.getFrameForComponent( thisFrame ),
																   "Color/Pattern legend is empty !", 
																   "Edit Color/Pattern Legend", 
																   JOptionPane.WARNING_MESSAGE );
								}
							} else if ( selectedCD == CDTypes.PROPORTIONAL_SYMBOLS ){
								if ( thematicMap.getAnnotations() != null ) {
									JDialogEditProportionalSymbolsLegend dlg =new JDialogEditProportionalSymbolsLegend( JOptionPane.getFrameForComponent( thisFrame ), 
																										  true, thisFrame.thematicMap.getAnnotations() );
									
									dlg.setVisible( true );
									
									dlg.dispose();
									
									repaintThematicMap();
								} 
							}
						}
					});
		}
		return jButtonEditLegend;
	}
		
	/**
	 * This method initializes jButtonTitleEdit	
	 * 	
	 * @return JButton	
	 */
	private JButton getJButtonTitleEdit() {
		if (jButtonTitleEdit == null) {
			jButtonTitleEdit = new JButton();
			jButtonTitleEdit.setText("Edit...");
			jButtonTitleEdit.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JDialogEditMultiLineString dlg =new JDialogEditMultiLineString( 
							JOptionPane.getFrameForComponent( thisFrame ), true, 
							"Edit Title", thematicMap.getAnnotations().getTitle() );
					dlg.setVisible( true );
					if ( dlg.isOkPressed() ) {
						thematicMap.getAnnotations().setTitle( dlg.getInputStr() );
						thematicMap.getAnnotations().setTitleEditedByUser( true );
						setDirty();
						repaintThematicMap();
					}
					dlg.dispose();
		        	
				}
			});
		}
		return jButtonTitleEdit;
	}
	/**
	 * This method initializes jButtonLegendTextEdit	
	 * 	
	 * @return JButton	
	 */
	private JButton getJButtonLegendTextEdit() {
		if (jButtonLegendTitleEdit == null) {
			jButtonLegendTitleEdit = new JButton();
			jButtonLegendTitleEdit.setText("Edit Title...");
			jButtonLegendTitleEdit.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JDialogEditMultiLineString dlg =new JDialogEditMultiLineString( 
							JOptionPane.getFrameForComponent( thisFrame ), true, 
							"Edit Legend Title", thematicMap.getAnnotations().getLegendText() );
					dlg.setVisible( true );
					if ( dlg.isOkPressed() ) {
						thematicMap.getAnnotations().setLegendText( dlg.getInputStr() );
						setDirty();
						repaintThematicMap();
					}
					dlg.dispose();	
				}
			});
		}
		return jButtonLegendTitleEdit;
	}
	
	/**
	 * This method initializes jComboBoxLabelColumn	
	 * 	
	 * @return JComboBox	
	 */
	private JComboBox getJComboBoxLabelColumn() {
		if (jComboBoxLabelColumn == null) {
			jComboBoxLabelColumn = new JComboBox();
			jComboBoxLabelColumn.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					
					if ( enableComboBoxLabelColumnEvent ) {
						setDirty();
						
						retrieveAnnotations();
						
						try {
							Map<MapShape, Object> data =new CartographicDisplayHelper()
																.assignValues( mtk, 
																        	   thematicMap.getData(),
																        	   mtk.getThematicMap().getCartographicDisplay() );
						} catch (TMapException e1) {
							new MiscUIHelper().displayErrorMessage( thisFrame, e1 );
						}
						
						mtk.repaint();
					}
				}

			});
		}
		return jComboBoxLabelColumn;
	}
	
} 
